﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Security.Cryptography;
namespace Pufang.Execl.BusinessCompute.XMLUtilities
{

    public class CRSAEncrypt
    {


        public string xmlkeys = @"<RSAKeyValue><Modulus>wVEhDSKrncEfuwaumEl3TpOgGpwOXcopyhx04sgtteSIK/W2tNyXlgNwb7L6cH0Rd3Xlc0FZ3z3ctkVXuGOvw+VCudBi

e/iuUVof2u1NBzPyh0N7pzu3JuuQEUzSWP+k/j0kuTXhK4ym2r5ifhmrcax40N67JzbXpoITUCHo/N0=</Modulus><Exponent>AQAB</Exponent

><P>/jK67PoSXoOmAAjYNwFO9ckr8Npvf7msQrofvuZLgeYpdmUX1hXyCXN1je5FdLk5PMUaMGbFAMi+uJBvFdvSew==</P><Q>wq/sYbDeJQC2sMm

j+qzNmjKSMRRR1EAg/bt7Tl8TYDNQDe42PVQjza+C9PD5x3625NqpNEX8qfaPvB+6QG2ahw==</Q><DP>QeMuVlxfRIZFEb85I9DAAa86J3zG58ldo

BIURmv06F+bIagEbKZVjSOTNc2rzRxxfJHuPtt0dsaRwM8XLAhFXw==</DP><DQ>nVrnqcX0pt++yYEQwols3JbHRlfwE6eJgstHzH5YAMc4iyngOQ

2KqrKTHDqxCCdI2AxL+m4e25jnb9wNBAoSfQ==</DQ><InverseQ>WinIFYpQYE0fBH9FJd502jOvpBNQwSxAU212oYHle5s2WWbM7ow1xehgE9GQi

dwPje2hExByn91yFdP3Wngnxw==</InverseQ><D>P8X31VF+tAgl45kMuAhkZ3Oj+aNJyf8LUjWZCcdn7P17PqVMpNWw3Dg+O1sb60gXHwWxsBf7A

f5ydV7i1V1teepuFyzb1BHOyXugnoPepSF6JFgBF0cf3BjqHeBRLaHZiOs/isxP5MWAwH1Jis+bbzzS5fNCFJXm4gVolD/QX7E=</D></RSAKeyVal

ue>";
        public string xmlPublicKey = @"<RSAKeyValue><Modulus>wVEhDSKrncEfuwaumEl3TpOgGpwOXcopyhx04sgtteSIK/W2tNyXlgNwb7L6cH0Rd3Xlc0FZ3z3ctkVXuGOvw+VCudBi

e/iuUVof2u1NBzPyh0N7pzu3JuuQEUzSWP+k/j0kuTXhK4ym2r5ifhmrcax40N67JzbXpoITUCHo/N0=</Modulus><Exponent>AQAB</Exponent

></RSAKeyValue>";
        /// <summary>
        /// 
        /// </summary>
        /// <param name="priKey">私钥</param>
        /// <param name="pubKey">公钥</param>
        /// <returns>ERROR -1:key生成出错
        ///          NOERROR 0:key生成成功
        /// </returns>
        static public int GEN_Key(out string priKey, out string pubKey)
        {
            priKey = null;
            pubKey = null;

            //OAEP padding is only available on Microsoft Windows XP or later

            try
            {
                RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
                pubKey = Convert.ToBase64String(RSA.ExportCspBlob(false));
                priKey = Convert.ToBase64String(RSA.ExportCspBlob(true));
                RSA.Clear();
            }
            catch (Exception e)
            {
                return -1;
            }
            return 0;
        }

        /// <summary>
        /// RSA解密
        /// </summary>
        /// <param name="scFileName">打开文件</param>
        /// <param name="svFileName">保存文件</param>
        /// <param name="prikey">私钥</param>
        /// <returns>ERROR -1:解密出错 1:参数不能为NULL 2:其它错误
        ///          NOERROR 0:解密成功
        /// </returns>
        static public int RSADecrypt(String scFileName, String svFileName, String prikey)
        {
            byte[] DataToDecrypt = null;
            byte[] DecryptedData = null;

            if (scFileName == null || svFileName == null
                || prikey == null
                || scFileName.Length == 0
                || svFileName.Length == 0)
                return 1;
            if (!File.Exists(scFileName))
                return 1;
            try
            {
                Stream bstrm = File.Open(scFileName, FileMode.Open, FileAccess.Read);

                DataToDecrypt = new byte[bstrm.Length];
                bstrm.Read(DataToDecrypt, 0, (int)bstrm.Length);
                bstrm.Close();
            }
            catch (Exception ex)
            {
                return 2;
            }
            try
            {
                RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
                byte[] keybuff = Convert.FromBase64String(prikey);
                RSA.ImportCspBlob(keybuff);

                int keySize = RSA.KeySize / 8;

                byte[] buffer = new byte[keySize];

                MemoryStream msInput = new MemoryStream(DataToDecrypt);

                MemoryStream msOutput = new MemoryStream();

                int readLen = msInput.Read(buffer, 0, keySize);

                while (readLen > 0)
                {

                    byte[] dataToDec = new byte[readLen];

                    Array.Copy(buffer, 0, dataToDec, 0, readLen);

                    byte[] decData = RSA.Decrypt(dataToDec, false);

                    msOutput.Write(decData, 0, decData.Length);

                    readLen = msInput.Read(buffer, 0, keySize);

                }

                msInput.Close();

                DecryptedData = msOutput.ToArray();    //得到解密结果

                msOutput.Close();

                RSA.Clear();
            }
            catch (CryptographicException e)
            {
                return -1;
            }

            if (DecryptedData == null)
                return 2;
            try
            {
                Stream wstrm = File.Open(svFileName, FileMode.Create, FileAccess.Write);

                wstrm.Write(DecryptedData, 0, DecryptedData.Length);

                wstrm.Flush();

                wstrm.Close();


            }
            catch (Exception exc)
            {
                return 2;
            }
            return 0;
        }

        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="scFileName">打开文件</param>
        /// <param name="svFileName">保存文件</param>
        /// <param name="pubkey">公钥</param>
        /// <returns>ERROR -1:加密出错 1:参数不能为NULL
        ///          NOERROR 0:加密成功
        /// </returns>
        static public int RSAEncrypt(String scFileName, String svFileName, String pubkey)
        {
            byte[] DataToEncrypt = null;
            byte[] EncryptedData = null;

            if (scFileName == null || svFileName == null
                || pubkey == null
                || scFileName.Length == 0
                || svFileName.Length == 0)
                return 1;
            if (!File.Exists(scFileName))
                return 1;
            try
            {
                Stream bstrm = File.Open(scFileName, FileMode.Open, FileAccess.Read);

                DataToEncrypt = new byte[bstrm.Length];
                bstrm.Read(DataToEncrypt, 0, (int)bstrm.Length);
                bstrm.Close();
            }
            catch (Exception ex)
            {
                return 2;
            }
            try
            {
                RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
                byte[] keybuff = Convert.FromBase64String(pubkey);
                RSA.ImportCspBlob(keybuff);

                int keySize = RSA.KeySize / 8;

                int bufferSize = keySize - 11;

                byte[] buffer = new byte[bufferSize];

                MemoryStream msInput = new MemoryStream(DataToEncrypt);

                MemoryStream msOutput = new MemoryStream();

                int readLen = msInput.Read(buffer, 0, bufferSize);

                while (readLen > 0)
                {

                    byte[] dataToEnc = new byte[readLen];

                    Array.Copy(buffer, 0, dataToEnc, 0, readLen);

                    byte[] encData = RSA.Encrypt(dataToEnc, false);

                    msOutput.Write(encData, 0, encData.Length);

                    readLen = msInput.Read(buffer, 0, bufferSize);

                }

                msInput.Close();

                EncryptedData = msOutput.ToArray();    //得到加密结果

                msOutput.Close();

                RSA.Clear();
            }
            catch (CryptographicException e)
            {
                return -1;
            }

            if (EncryptedData == null)
                return 2;
            try
            {

                Stream wstrm = File.Open(svFileName, FileMode.Create, FileAccess.Write);

                wstrm.Write(EncryptedData, 0, EncryptedData.Length);

                wstrm.Flush();

                wstrm.Close();


            }
            catch (Exception exc)
            {
                return 2;
            }
            return 0;
        }

    }
}